﻿using System;
using System.Collections.Generic;
using System.Linq;
using orienta.Models;
using orienta.ViewModels;
using orienta.Utils;
using System.Data.Objects;

namespace orienta.Helper
{

    public class SolicitudHelper
    {
        private GoodTireEntities db = new GoodTireEntities();


        public class SolicitudPaso
        {
            public string DescDep { get; set; }
            public decimal CodDep { get; set; }
        }

        /*Lista de la bandeja de ENTRADA / SALIDA
         */
        public List<SolicitudBandeja> getSolicitudList(decimal estado,decimal nIdeDep, decimal nTipoActor, DateTime fechaIni, DateTime fechaFin, int nroTramites, int nroPagina, ref  int totalRegistros)
        {
            int skip = (nroPagina - 1)* nroTramites;

           
            
            //String sql = (a as ObjectQuery).ToTraceString();

            var detalleList = (
                from actor in db.ORIDetSoliActor
                join detalle in db.ORIDetSolicitud on new { actor.nIdeSolicitud, actor.nSeqPaso} equals new { detalle.nIdeSolicitud, detalle.nSeqPaso }
                join solicitud in db.ORIMaeSolicitud on actor.nIdeSolicitud equals solicitud.nIdeSolicitud
                join programa in db.ORIDetCompendio on solicitud.nIdePrograma equals programa.nIdeDetalle
                join clase in db.ORIDetCompendio on solicitud.nIdeClaseSolicitud equals clase.nIdeDetalle
                join tipo in db.ORIDetCompendio on solicitud.nTipoSolic equals tipo.nIdeDetalle
                join estadoDetalle in db.ORIDetCompendio on detalle.nIdeEstado equals estadoDetalle.nIdeDetalle
                join persona in db.ORIMaePersona on solicitud.nIdePersonSolicita equals persona.nIdePersona
                join afectado in db.ORIMaePersona on solicitud.nIdePersonAfectado equals afectado.nIdePersona
                where (actor.nIdeDep == nIdeDep) &&
                      (actor.nIdeTipoActor == nTipoActor) &&
                      (actor.dtFecRecepcion >= fechaIni) &&
                      (actor.dtFecRecepcion < fechaFin) &&
                      (actor.dtFecDerivacion == null || actor.nIdeTipoActor == 1) &&
                      (estado == 0 || detalle.nIdeEstado == estado)
                select new SolicitudBandeja()
                {
                    //fechaRecepcion =detalle.dtFecReg,
                    plazo = detalle.nPlazo.Value,
                    nIdeSolicitud = actor.nIdeSolicitud,
                    nIdeDep = solicitud.nIdeDep,
                    clase = clase.vNomDetalle,
                    tipo = tipo.vNomCorto,
                    programa = programa.vNomDetalle,
                    solicitante = persona.vNumDocum + " " + persona.vPriNombre + " " + persona.vPriApellido,
                    afectado = afectado.vNumDocum + " " + afectado.vPriNombre + " " + afectado.vPriApellido,
                    nAnnSolicitud = solicitud.nAnnSolicitud,
                    fechaEntrada = actor.dtFecRecepcion,
                    fechaRecepcion = actor.dtFecRecFisica,
                    fechaLectura = actor.dtFecLectura,
                    nSeqActor = actor.nSeqActor,
                    nSeqPaso = actor.nSeqPaso,
                    nNumSolicitud = solicitud.nNumCorrelativo,
                    estado = estadoDetalle.vNomCorto
                }).Distinct();
            totalRegistros = detalleList.ToList().Count;
           // totalPaginas = (int)Math.Truncate((float)totalPaginas / (float)nroTramites) + 1;
           // String s = (ObjectQuery)detalleList).ToTraceString();

            return detalleList.Distinct().OrderBy(m=>m.nIdeSolicitud ).Skip(skip).Take(nroTramites).ToList();
        }


        public List<SolicitudBandeja> getSolicitudBuscar(decimal estado, decimal nTipoActor, decimal nIdClase, decimal nIdeDep, decimal anio, decimal correlativo)
        {

            var detalleList = (
                from actor in db.ORIDetSoliActor
                join detalle in db.ORIDetSolicitud on new { actor.nIdeSolicitud, actor.nSeqPaso } equals new { detalle.nIdeSolicitud, detalle.nSeqPaso }
                join solicitud in db.ORIMaeSolicitud on actor.nIdeSolicitud equals solicitud.nIdeSolicitud
                join programa in db.ORIDetCompendio on solicitud.nIdePrograma equals programa.nIdeDetalle
                join clase in db.ORIDetCompendio on solicitud.nIdeClaseSolicitud equals clase.nIdeDetalle
                join tipo in db.ORIDetCompendio on solicitud.nTipoSolic equals tipo.nIdeDetalle
                join persona in db.ORIMaePersona on solicitud.nIdePersonSolicita equals persona.nIdePersona
                join afectado in db.ORIMaePersona on solicitud.nIdePersonAfectado equals afectado.nIdePersona
                join estadoDetalle in db.ORIDetCompendio on detalle.nIdeEstado equals estadoDetalle.nIdeDetalle
                where (actor.nIdeDep == nIdeDep) &&
                      (actor.nIdeTipoActor == nTipoActor) &&
                      (solicitud.nIdeClaseSolicitud == nIdClase) &&
                      (solicitud.nAnnSolicitud == anio) &&
                      (solicitud.nNumCorrelativo == correlativo) &&
                      (actor.dtFecDerivacion == null || actor.nIdeTipoActor == 1) &&
                      (estado == 0 || detalle.nIdeEstado == estado)
                select new SolicitudBandeja()
                {
                    plazo = detalle.nPlazo.Value,
                    nIdeSolicitud = actor.nIdeSolicitud,
                    nIdeDep = solicitud.nIdeDep,
                    clase = clase.vNomDetalle,
                    tipo = tipo.vNomCorto,
                    programa = programa.vNomDetalle,
                    solicitante = persona.vNumDocum + " " + persona.vPriNombre + " " + persona.vPriApellido,
                    afectado = afectado.vNumDocum + " " + afectado.vPriNombre + " " + afectado.vPriApellido,
                    nAnnSolicitud = solicitud.nAnnSolicitud,
                    fechaEntrada = actor.dtFecRecepcion,
                    fechaRecepcion = actor.dtFecRecFisica,
                    fechaLectura = actor.dtFecLectura,
                    nSeqActor = actor.nSeqActor,
                    nSeqPaso = actor.nSeqPaso,
                    nNumSolicitud = solicitud.nNumCorrelativo,
                    estado = estadoDetalle.vNomCorto
                });



            return detalleList.ToList();
        }


        public decimal getCorrelativoSolicitud(decimal anio,decimal claseSolicitud, decimal nideDep)
        {
            //String sql = "select isnull(max(nNumCorrelativo),0) + 1 from ORIMaeSolicitud where nIdeClaseSolicitud=" + claseSolicitud + " and ";
            String sql = "select isnull(MAX(nNumCorrelativo),0) + 1 from ORIMaeAreaNumera where nIdeDep=" + nideDep + " AND nAnoCorre=" + anio + " AND nIdeClaseSolicitud=" + claseSolicitud;
            var max = db.ExecuteStoreQuery<Decimal>(sql);
            List<Decimal> valores = max.ToList<Decimal>();
            Decimal secuencia = valores.First<Decimal>();

            return secuencia;
        }

        public decimal getSeqPasoEvento(Decimal nIdeSolicitud)
        {

            String sql = "select isnull(max(nSeqPaso),0) + 1 from ORIDetSolicitud where nIdeSolicitud=" + nIdeSolicitud;
            var max = db.ExecuteStoreQuery<Decimal>(sql);
            List<Decimal> valores = max.ToList<Decimal>();
            Decimal secuencia = valores.First<Decimal>();

            return secuencia;
        }


        public List<String> cargarDerivados(ORIDetSolicitud detSolicitud, String sDerivados, ORIMaeUsuario usuario)
        {
            List<String> error = new List<String>();
            String[] arrDerivados = sDerivados.Split(',');
            ORIDetSoliActor detSoliActor = new ORIDetSoliActor();
            int nSeqActor = 1;
            detSoliActor.nSeqActor = nSeqActor;
            detSoliActor.nIdeTipoActor = Constantes.SOLICITUD_TIPO_ACTOR.QUE_DERIVA;
            detSoliActor.nIdeTipoCategoria = Constantes.SOLICITUD_CATEGORIA.PERSONA;
            detSoliActor.nIdeDep = usuario.nIdeDep.Value;
            detSoliActor.dtFecRecepcion = DateTime.Now;
            detSoliActor.dtFecDerivacion = DateTime.Now;
            detSoliActor.dtFecRecFisica = DateTime.Now;
            detSoliActor.nIdeFuncionario = usuario.nIdeFuncionario;
            detSolicitud.ORIDetSoliActor.Add(detSoliActor);

            foreach (String derivado in arrDerivados)
            {
                nSeqActor++;
                String sNombreIdTipo = derivado;
                int limiteInicio = sNombreIdTipo.IndexOf('<');
                int limiteGuion = sNombreIdTipo.LastIndexOf('-');
                int limiteFin = sNombreIdTipo.IndexOf('>');
                if (limiteInicio > -1)
                {
                    String sIdDerivado = sNombreIdTipo.Substring(limiteInicio + 1, limiteGuion - limiteInicio - 1);
                    String sAreaDerivado = sNombreIdTipo.Substring(limiteGuion + 1, limiteFin - limiteGuion - 1);
                    decimal nIdDerivado = Convert.ToInt32(sIdDerivado);

                    detSoliActor = new ORIDetSoliActor();
                    detSoliActor.nSeqActor = nSeqActor;
                    detSoliActor.nIdeTipoActor = Constantes.SOLICITUD_TIPO_ACTOR.QUE_ES_DERIVADO;
                    detSoliActor.dtFecRecepcion = DateTime.Now;

                    if (sAreaDerivado.Equals("A"))
                    {
                        try
                        {
                            ORIMaeDependencia dependecia = db.ORIMaeDependencia.Single(o => o.nIdeDep == nIdDerivado);
                            detSoliActor.nIdeTipoCategoria = Constantes.SOLICITUD_CATEGORIA.AREA;
                            detSoliActor.nIdeDep = dependecia.nIdeDep;
                        }
                        catch (Exception)
                        {
                            error.Add("La dependencia con codigo='" + sIdDerivado + "' no existe");
                        }
                    }
                    else
                    {
                        try
                        {
                            ORIMaeFuncionario funcionario = db.ORIMaeFuncionario.Single(o => o.nIdeFuncionario == nIdDerivado);
                            detSoliActor.nIdeTipoCategoria = Constantes.SOLICITUD_CATEGORIA.PERSONA;
                            detSoliActor.nIdeDep = usuario.nIdeDep.Value;
                            detSoliActor.nIdeFuncionario = funcionario.nIdeFuncionario;

                        }
                        catch (Exception)
                        {
                            error.Add("El funcionario con codigo='" + sIdDerivado + "' no existe");
                        }

                    }

                    detSolicitud.ORIDetSoliActor.Add(detSoliActor);
                }

            }

            return error;

        }


        public decimal getIdPersona()
        {
            String sql = "select isnull(max(nIdePersona),0) + 1 from ORIMaePersona";
            var max = db.ExecuteStoreQuery<Decimal>(sql);
            List<Decimal> valores = max.ToList<Decimal>();
            Decimal secuencia = valores.First<Decimal>();

            return secuencia;
        }


        public List<ORIDetCompendio> getCompendioGrupo(decimal nIdeGrupo)
        {

            var detalleList = (
                from  detalle in db.ORIDetCompendio
                join grupo in db.ORIDetCompGrupo on detalle.nIdeDetalle equals grupo.nIdeDetalle
                where grupo.nIdeDetElemento == nIdeGrupo
                select  detalle );

            return detalleList.ToList();
        }

        public IList<DireccionesView> ListarDirecciones(int idPersona)
        {
            return db.uspListarDirecciones(idPersona).ToList();
        }

    }



    /**
     join programa in db.ORIDetCompendio c on c.nIdeDetalle = s.nIdePrograma
                
     */
}